package com.blue.firecat.serivce.impl;

import com.blue.firecat.contants.Contants;
import com.blue.firecat.contants.Result;
import com.blue.firecat.dao.OrderDao;
import com.blue.firecat.dao.TradeDao;
import com.blue.firecat.dao.UserDao;
import com.blue.firecat.entity.*;
import com.blue.firecat.enums.ErrorEnum;
import com.blue.firecat.enums.OrderTypeEnum;
import com.blue.firecat.enums.TradeStatusEnum;
import com.blue.firecat.enums.UserTypeEnum;
import com.blue.firecat.serivce.GameService;
import com.blue.firecat.serivce.OrderService;
import com.blue.firecat.serivce.TradeService;
import com.blue.firecat.serivce.UserService;
import com.blue.firecat.utils.email.EmailUtils;
import com.blue.firecat.utils.mapper.BeanMapper;
import com.blue.firecat.vo.OrderVo;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @描述
 * @时间 2017/6/22 22:26
 * @作者 肖亦鸣
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderDao orderDao;
    @Autowired
    TradeDao tradeDao;
    @Autowired
    UserDao userDao;
    @Autowired
    TradeService tradeService;
    @Autowired
    UserService userService;
    @Autowired
    GameService gameService;

    @Override
    public void countByExample(OrderExample example) {
        List<Order> orders = orderDao.selectByExample(example);
        if (CollectionUtils.isEmpty(orders)) {
            return;
        }
        //给各种订单加1
        for (Order order : orders) {
            Contants.ORDER_COUNT_MAP.put(order.getTypeString(), Contants.ORDER_COUNT_MAP.get(order.getTypeString()) + 1);
            //如果 是未接手的
            if (order.getType().equals(OrderTypeEnum.WAITING.getCode())) {
                Contants.GAME_COUNT_MAP.put(order.getGameId(), Contants.GAME_COUNT_MAP.get(order.getGameId()) + 1);
            }
        }
    }

    /**
     * 增加订单,是否选择打手逻辑处理
     *
     * @param record
     * @return
     */
    @Override
    public Result<Order> insertSelective(Order record, User user) throws Exception {
        Result<Order> result = new Result<>();
        if (record == null || record.getId() == null) {
            result.setCode(ErrorEnum.ORDER_DATA_ERROR);
            return result;
        }
        Order order = orderDao.selectByPrimaryKey(record.getId());
        if (order != null) {
            result.setCode(ErrorEnum.ORDER_EXITS);
            return result;
        }
        //1.必须是管理员 或者客服
        if (Contants.verifyAuthorityOrCustom(user, result)) return result;
        record.setType(OrderTypeEnum.WAITING.getCode());
        Game game = gameService.selectByPrimaryKey(record.getGameId());
        if (game != null) {
            record.setGameName(game.getName());
        }
        User userCreate = userDao.selectByPrimaryKey(user.getId());
        if (userCreate != null) {
            record.setName(userCreate.getName());
        }
        record.setOperate(userCreate.getUserName());
        record.setUserId(user.getId());
        orderDao.insertSelective(record);
        this.appointBeater(record, user);
        result.setData(record);
        return result;
    }

    @Override
    public Result<Order> updateByPrimaryKeySelective(Order order, User user) {
        Result<Order> result = new Result<>();
        //1.必须是管理员 或者客服
        if (Contants.verifyAuthorityOrCustom(user, result)) return result;

        Order orderPersistent = orderDao.selectByPrimaryKey(order.getId());
        if (orderPersistent == null) {
            result.setCode(ErrorEnum.ORDER_DOES_NOT_EXIST);
            return result;
        }
        Game game = gameService.selectByPrimaryKey(order.getGameId());
        if (game != null) {
            order.setGameName(game.getName());
        }
        User userPersistent = userDao.selectByPrimaryKey(user.getId());
        if (userPersistent != null) {
            order.setName(userPersistent.getName());
        }
        System.out.println(order);
        orderDao.updateByPrimaryKeySelective(order);
        //如果是异常单,需要把交易的改成代练中
        if (orderPersistent.getType().equals(OrderTypeEnum.ABNORMAL_ORDERS.getCode())) {
            TradeExample example = new TradeExample();
            example.getOredCriteria().add(example.createCriteria().andOrderIdEqualTo(order.getId()));
            List<Trade> trades = tradeDao.selectByExample(example);
            if (CollectionUtils.isNotEmpty(trades)) {
                Trade trade = trades.get(0);
                Long tradeId = trade.getId();
                BeanMapper.copy(order, trade);
                trade.setId(tradeId);
                trade.setUserId(null);
                trade.setUserName(null);
                trade.setUserId2(order.getUserId());//客服id
                trade.setUpdateTime(new Date());
                //设置成代练中
                trade.setStatus(TradeStatusEnum.IS_WORK.getCode());
                tradeDao.updateByPrimaryKeySelective(trade);
            }
        }
        //如果指定打手,则新增交易记录,并且更新订单为指派订单
        this.appointBeater(order, user);
        result.setData(order);
        return result;
    }

    @Override
    public Result<List<Order>> selectByExample(OrderVo orderVo, User user) {
        Result<List<Order>> result = new Result<>();
        OrderExample example = new OrderExample();
        OrderExample.Criteria criteria = example.createCriteria();
        example.getOredCriteria().add(criteria.andGameIdEqualTo(orderVo.getGameId())
                .andIdEqualTo(orderVo.getOrderId())
                .andUserIdEqualTo(orderVo.getUserId())
                .andSettlePriceBetween(orderVo.getPriceMin(), orderVo.getPriceMax())
                .andTypeEqualTo(orderVo.getOrderTypeSelect())
                .andCreateTimeBetween(orderVo.getDateMin(), orderVo.getDateMax()));

        if (user != null) {
            //如果是用户,返回未接手的订单
            if (user.getType().equals(UserTypeEnum.BEATER.getCode())) {
                example.getOredCriteria().add(criteria.andTypeEqualTo(OrderTypeEnum.WAITING.getCode()));
            }
            //如果是客服或者管理员 这里不做限制,可以查询所有记录
            else if (user.getType().equals(UserTypeEnum.CUSTOM_SERVICE.getCode())
                    || user.getType().equals(UserTypeEnum.ADMIN.getCode())) {

            }
        }
        List<Order> orders = orderDao.selectByExample(example);

        if (CollectionUtils.isEmpty(orders)) {
            result.setCode(ErrorEnum.ORDER_DOES_NOT_EXIST);
        }
        //如果用户是打手,需要将一些参数给隐藏起来
        this.clearOrder(user, orders);
        result.setData(orders);
        return result;
    }

    /**
     * 删除订单数据 1.必须是管理员 2.只能是 过期,未接手,订单异常,
     *
     * @param orderVo
     * @param user
     * @return
     */
    @Override
    public Result<Order> deleteByPrimaryKey(OrderVo orderVo, User user) {
        Result<Order> result = new Result<>();
        //1.必须是管理员
        if (Contants.verifyAuthority(user, result)) return result;
        Order order = orderDao.selectByPrimaryKey(orderVo.getOrderId());
        if (order == null) {
            result.setCode(ErrorEnum.ORDER_DOES_NOT_EXIST);
            return result;
        }
        //2.只能是 过期(EXPIRED),未接手,订单异常 ()
        if (order.getType().equals(OrderTypeEnum.WAITING.getCode())
                || order.getType().equals(OrderTypeEnum.WAITING.getCode())
                || order.getType().equals(OrderTypeEnum.ABNORMAL_ORDERS.getCode())) {
            //删除订单
            int i = orderDao.deleteByPrimaryKey(orderVo.getOrderId());
            //删除交易
            TradeExample example = new TradeExample();
            example.getOredCriteria().add(example.createCriteria().andOrderIdEqualTo(orderVo.getOrderId()));
            tradeDao.deleteByExample(example);
            if (i == 0) {
                result.setCode(ErrorEnum.ORDER_DELETE_ERROR);
                return result;
            }
        } else {
            result.setCode(ErrorEnum.ORDER_NO_DELETE);
            return result;
        }
        return result;
    }

    @Override
    public Result<Map<Integer, String>> getOrderType() {
        Result<Map<Integer, String>> result = new Result<>();
        Map<Integer, String> map = Maps.newHashMap();
        OrderTypeEnum[] values = OrderTypeEnum.values();
        for (OrderTypeEnum orderTypeEnum : values) {
            map.put(orderTypeEnum.getCode(), orderTypeEnum.getValue());
        }
        result.setData(map);
        return result;
    }

    @Override
    public Result<Order> selectByPrimaryKey(Long orderId) {
        Result<Order> result = new Result<>();
        Order order = orderDao.selectByPrimaryKey(orderId);
        if (order == null) {
            return result;
        }
        order.setGamePassword("***********");
        order.setPhone(null);
        order.setSettlePrice(null);
        order.setOrderPrice(null);
        result.setData(order);
        return result;
    }

    @Override
    public void setExpired() {
//        OrderExample example = new OrderExample();
//        example.getOredCriteria().add(example.createCriteria()
//                .andAllTimeNotEqualTo(0)
//                .andTypeNotIn(Arrays.asList(OrderTypeEnum.EXPIRED.getCode(),
//                        OrderTypeEnum.HAS_BEEN_SETTLED.getCode(),
//                        OrderTypeEnum.ABNORMAL_ORDERS.getCode())));
//        List<Order> orders = orderDao.selectByExample(example);
//        for (Order order : orders) {
//            long nowTime = order.getCreateTime().getTime() + order.getAllTime() * 60 * 60 * 1000;
//            if (nowTime <= System.currentTimeMillis()) {
//                order.setType(OrderTypeEnum.EXPIRED.getCode());
//                order.setAllTime(order.getAllTime() * 2);
//                orderDao.updateByPrimaryKey(order);
//            }
//        }

    }

    @Override
    public Result<Map<String, Integer>> countByExample(User user) {
        Result<Map<String, Integer>> result = new Result<>();
        //这个必须是管理员或者客服
        if (Contants.verifyAuthorityOrCustom(user, result)) return result;

        OrderExample example = new OrderExample();
        //是管理员或者客服
        if (user.getType().equals(UserTypeEnum.CUSTOM_SERVICE.getCode())) {
            example.getOredCriteria().add(example.createCriteria()
                    .andUserIdEqualTo(user.getId())
                    .andTypeNotEqualTo(TradeStatusEnum.UNKNOWN.getCode()));
        } else {
            example.getOredCriteria().add(example.createCriteria()
                    .andTypeNotEqualTo(TradeStatusEnum.UNKNOWN.getCode()));
        }

        List<Order> orders = orderDao.selectByExample(example);
        if (CollectionUtils.isEmpty(orders)) {
            result.setCode(ErrorEnum.ORDER_DOES_NOT_EXIST);
            return result;
        }
        Map<String, Integer> map = new TreeMap<>();
        for (Order order : orders) {
            if (map.get(order.getTypeString()) == null) {
                map.put(order.getTypeString(), 1);
            } else {
                map.put(order.getTypeString(), map.get(order.getTypeString()) + 1);
            }
        }
        result.setData(map);
        return result;
    }

    @Override
    public Object count() {
        return orderDao.countByExample(null);
    }

    @Override
    public Result<Order> selectByPrimaryKey(Long id, User user) {
        Result<Order> result = new Result<>();
        Order order = orderDao.selectByPrimaryKey(id);
        this.clearOrder(user, Collections.singletonList(order));
        result.setData(order);
        return result;
    }

    private void appointBeater(Order record, User user) {
        //如果指定打手,则新增交易记录,并且更新订单为指派订单
        if (record.getBeaterId() != null) {
            record.setType(OrderTypeEnum.APPOINT_BEATER.getCode());
            record.setOperate(user.getName());
            Result<User> userBeater = userService.selectByPrimaryKey(record.getBeaterId(), user);
            Trade trade = new Trade();
            trade.setOrderId(record.getId());
            trade.setStatus(TradeStatusEnum.APPOINT_BEATER.getCode());
            trade.setOperate(user.getName());
            tradeService.insertSelective(userBeater.getData(), trade);
            orderDao.updateByPrimaryKeySelective(record);
            try {
                EmailUtils emailUtils = new EmailUtils("", userDao.selectByPrimaryKey(record.getBeaterId()).getEmail(), trade.getOrderId().toString());
                emailUtils.send(4);
            } finally {
            }
        }
    }

    /**
     * 清除 订单相关信息
     *
     * @param user
     * @param orders
     */
    private void clearOrder(User user, List<Order> orders) {
        if (Contants.isBeater(user)) {
            for (Order order : orders) {
                order.setUserId(null);
                order.setGameUserName("*********");
                order.setWw("*********");
                order.setQq(null);
                order.setPhone(null);
                order.setGameUser("*********");
                order.setGameUserChild("*********");
                order.setGamePassword("*********");
                order.setOrderPrice(null);
                order.setOperate("*********");
            }
        }
    }
}
